//======================================================================
/// COPYRIGHT CATT
/// @file        MacroDef.h
///
/// @brief     宏定义文件
/// @author      LiangFengnian
/// @note        暂无
/// @par History
/// -
///       Date|       Author|        Version|        DESCRIPTION
/// ----------|-------------|---------------|-------------------
/// 2017-09-29|LiangFengnian|          0.0.1|            created
//======================================================================
#ifndef _MacroDef_h_
#define _MacroDef_h_

#include "math.h"
#include "stdio.h"
#include "stdlib.h"

/****************************************************
                   macro define
*****************************************************/
#ifndef FILESPRINT
#define FILESPRINT 0 //!< 文件打印宏开关，1 ：打印使能；0 ：打印不使能
#else
#define tft_tv_print_en			1
#endif

#ifndef FILESPRINTDL
//#define DMRSINDEX_Fixp_FPRINTF  0 // cpp文件中目前都是使用的 "ifdef  DMRSINDEX_Fixp_FPRINTF" 做的判断
#define FILESPRINTDL            0 //!< 文件打印宏开关，1 ：打印使能；0 ：打印不使能
#define pdsch_mimo_vt_print_en  0
#define pdsch_decode_vt_print_en  0
#define csi_rs_vt_print_en  0
//#define tft_tv_print_en			1
#else
#define DMRSINDEX_Fixp_FPRINTF  1 // PBCH SSBIndex检测打印使能：1 ：打印使能；0 ：打印不使能
#endif
#define LTEMIMO_TEST_PRINT  0
#define FILESPRINT_ZX 0 //!< for ZhanXun, 文件打印宏开关，1 ：打印使能；0 ：打印不使能
#define FIX_TYPE_PBCH 0  // Fixed point, RX parameter, 0 for CEVA DSP, 1 for FPGA
// #define FILESPRINT_PBCH 1  // Fixed point, RX parameter, 0 for CEVA DSP, 1 for FPGA
//#define    ULTEST_PRINTFLAG  (0) //上行测试向量打印开关
#ifndef ULTEST_PRINTFLAG
#define ULTEST_PRINTFLAG 1 //!< 上行测试向量文件打印宏开关，1 ：打印使能；0 ：打印不使能 
//可以通过nr_mail_ul里的全局变量DTYD_ULPrint_Flag=1在complier时将这个宏编译为1
#endif

#ifndef UE_TX_PRINTFLAG
#define UE_TX_PRINTFLAG  1   //=======上行CEVA测试向量文件打印宏开关，1 ：打印使能；0 ：打印不使能 

#define UE_SNRdbTestFlag  0

#define UE_SRS_PRINTFLAG 0 // SRS 测试向量打印。
#endif

#ifndef LDPC_SUPPORTMAXTBSFLAG
#define LDPC_SUPPORTMAXTBSFLAG 0 //!< 1: CW_MAX_LEN&MAX_CB_NUM定义较大的值支持最大TBS；0：CW_MAX_LEN&MAX_CB_NUM定义较小的值节省内存空间
//可以通过nr_mail_ul里的全局变量LDPC_SUPPORTMAXTBSFLAG=1在complier时将这个宏编译为1
#endif

#define PUSCH_CASE_NUM 53
#define AL_TRUE                  ((boolean)1)
#define AL_FALSE                 ((boolean)0)

#define CHE_AlGO_LI    0
#define CHE_AlGO_MMSE  1
#define CHE_AlGO_LINE_MEAN    2
#define SQRT2        1.41421356f
#define INV_SQRT2    0.70710678f  // 1/(sqrt(2))
#define INV_2SQRT2    0.35355339f // 1/(2*sqrt(2))
#define INV_SQRT3    0.57735027f  // 1/(sqrt(3))
#define INV_2SQRT3    0.28867513f // 1/(2*sqrt(3))
#define INV_SQRT10   0.31622777f
#define INV_SQRT42   0.15430335f
#define INV_SQRT170  0.07669650f    //256QAM

//#define PDCCH_BlindDecode_Flag        0 //0:不做盲检操作，1：盲检

#define IN
#define INOUT
#define OUT
//#define PI_FLTP 3.1415926535897932384626433832795f
#define PI_FLTP (3.141592653589793)  // \pi
#define PI_FIXP 25736 //Q(16,3)

#define E_FLTP 2.71828183f
#define RECIP_PI (INT16)10430 //1/Pi,Q(16,1)

//MIMO mode
#define MIMO_MODE_SANT  0   //single antenna port
#define MIMO_MODE_TXD   1   //transmit diversity
#define MIMO_MODE_SM    2   //spatial multiplexing
#define MIMO_MODE_MM    3   //MU-MIMO


//MIMO detection
#define MRC_IRC_CSI                0                 // 0 for MRC, 1 for IRC, 2 for MRC/IRC adaptive
#define MRC_IRC_SW                 0                 // 0 for MRC, 1 for IRC, 2 for MRC/IRC adaptive
#define MAX_DLRX_NUM               4
#define MAX_RS_NUM                 1650              // 275*6
#define MAX_MUMIMO_PORTNUM_DL      32
#define RS_NUM_PER_TTI_DL          4                //
#define MAX_INV_DIM                64               // hermitian_matrix_inv_gauss_f..
#define MAX_BITNUM_PER_SYM         6

//CP type
#define NORMAL_CP   0   //normal CP
#define EXTENDED_CP 1   //extended CP

//RS type
#define CRS 0   //cell specific reference signal
#define DRS 1   //ue specific reference signal
#define CSI_RS 2  //wnr add 20130512

#define MRC 0   //maximum ratio combine
#define IRC 1   //interference rejection combine
// LDPC

#define MAX_CBLEN_BG1  8448 //maximum length of one code block,BG1
#define MAX_CBLEN_BG2  3840 //maximum length of one code block,BG2

#define TD_AVG_FLAG 1 //1: LS时域上求平均，不做时域MMSE插值，0：代表LS结果先做频域MMSE，再做时域MMSE
#if ((1 == FILESPRINT)||(2 == FILESPRINT)||(3 == FILESPRINT)||(1 == ULTEST_PRINTFLAG)||(1 == LDPC_SUPPORTMAXTBSFLAG))
#define CW_MAX_LEN     2122848 //maximum length of one code word 273*12*13.5*6*MAX_CB_NUM
#else
#define CW_MAX_LEN     506880 //maximum length of one code word 66*384*MAX_CB_NUM
#endif

#if ((1 == FILESPRINT)||(2 == FILESPRINT)||(3 == FILESPRINT)||(1 == ULTEST_PRINTFLAG)||(1 == LDPC_SUPPORTMAXTBSFLAG))
#define MAX_CB_NUM     150     //maximum number of code block
#else
#define MAX_CB_NUM     56     //maximum number of code block
#endif
#define MAX_CB_DECLEN  26112   //maximum length of one code block decoding length,68*384
#define MAX_CB_RMLEN   253440  //maximum length of one code block after ratematching,66*384/0.1

#ifndef Print_PDCCH_Flag
#define Print_PDCCH_Flag 0 //!< 1: PDCCH打印, 0：PDCCH打印关闭
#define FILESPRINTDLPDCCH 0
#endif

#define GETBIT(a,b) (((a)>>(b))&1)

#define MAX_TX_ANT_NUM          64   // 最大传输天线数量
#define MAX_RX_ANT_NUM          4    // 最大接收天线数量
#define MAX_RSNUM_PER_RB        6
#define MAXSYMNUM               14
#define MAXRBNUM                273
#define FFT_SHIFT               0
#define MAXPORTNUM              32
#define RS_NUM_PER_TTI          4      //包含一个前置和三个后置
#define MAX_TRS_SYM_NUM         2
#define MAX_TRSNUM_PER_RB       3
#define MAX_RS_SYM_NUM          4
#define MAX_PDCCH_SYM_NUM       6
#define RS_NUM_PER_TTI_FRONT    2
#define MAX_PUSCH_TTI_LEN       122880     //added zhangyanqun
#define MAX_L_W                 165        //added zhangyanqun  max length of window
//#define   PORT_INDEX              0
#define  SLOT_NUM                1
#define  TRS_N_FS               75

#define SAMPLERATE              122880000
#define SC_PER_RB               12
#define AFT_DMRS_FLAG           0
#define AFT_DMRS_l              13
#define AFT_DMRS_Num            1

#define MAX_PUCCH_CODING_RATE   0.8

//physical channel & physical signal define
#define EMPTY_RE                0
#define PSS                     1    // 主同步信号
#define SSS                     2    // 辅同步信号
#define PBCH                    3
#define PDCCH                   4
#define PDCCH_DMRS              5
#define PDSCH                   6
#define CSIRS                   7
#define TRS                     8
#define PDSCH_DMRS               9
#define LTE_CRS                 10
#define RM_CORESET              11
#define RM_PATTERN              12
#define PTRS                    13 
#define NOCHAN                  100
#define RESERVERE               -1
//#define PCFICH 1
//#define PHICH  2
//#define EPDCCH  5
//#define PMCH  6
//
#define MAX_CORESET_NUM         4
#define  MAX_PDCCHNUM_CORESET   200 //90,200是支持打开盲检的最大candidate个数
#define MAX_AL_NUM              5 // 聚合等级AL个数
#define MAX_CCE_NUM             16
#define MAX_REG_NUM             6*MAX_CCE_NUM
#define REG_NUM_PER_CCE         6
#define MAX_REGBUNDLE_NUM       96
#define PDCCH_DMRS_NUM_RB       3
#define PDCCH_MAX_RXNUM         2
#define MAX_BWP_NUM             4
#define MAX_L                   64
#define MAX_FFT_SIZE            8192    //SS块最大FFFT Size，只能支持到100MHz
#define MAX_SCS_NUM             4       //最大SCS个数
#define MAX_CW_NUM              2
#define MAX_LAYER_NUM           8
#define MIMO_MODE_SANT          0
#define MIMO_MODE_TXD           1
#define MAX_CSI_NUM             12  //csi-rs配置最大个数
#define MAX_CSI_RENUM           8   //一个CSI-RS OCC对应的最大RE个数
#define MAX_CSI_SYMNUM          4   //一个CSI-RS OCC对应的最大symbol个数
#define MAX_CSI_PORTNUM         32   //CSI-RS最大端口个数
#define MAX_TRS_RBNUM           264   //TRS最大RB个数 //FDD配置TRS RB num = BWP size = 52RB，TDD 配置 TRS RB num = BWP size = 106,这里TRS统一分配成最大273RB
#define TRS_SYMNUM_PER_SLOT     2   //TRS每个Slot的符号个数
#define MAX_CSI_RBNUM           272   //CSIRS最大RB个数，协议规定必须是4的倍数
#define MAX_TRS_NUM             2   //TRS配置最大个数
#define MAX_DMRS_PORT_NUM     8

#define PDCCH_RE_MAPPING_WITH_INTERLEAVER 0  // 0 for PDCCH RE mapping without interleaver, 1 for with interleaver
#define MRC_IRC_ADG                0//0代表不开MRC_IRC自适应，固定MRC，1代表打开MRC_IRC自适应开关
//modulation
#define BPSK 0
#define QPSK 1
#define QAM16 2
#define QAM64 3
#define QAM256 4
#define APSK_8  3
#define APSK_16 4
#define APSK_32 5

//POLAR CODE
#define FSCL 0// Fast Successive Cancellation List
#define SCL  1 //Successive Cancellation List
#define FSCL_RTL  2 // Fast Successive Cancellation List, RTL style
#define FSCL_DSP  3 // Fast Successive Cancellation List, DSP style
#define XLX_POLAR 4 // use xilinx polar ip

//polar related macro
#define POLAR_MAX_RNTI_NUM          8
#define MAX_POLAR_LENGTH            1024 // 1013+11
#define MAX_E_LENGTH                8192
#define MAX_E_UCI                   16385
#define MAX_LIST_LENGTH             8
#define SWAP_LIST_LENGTH            8
#define MAX_POLAR_LAYER_NUM         11
#define K_MAX                       164
#define R_MIN                       0.125
#define N_PC_MAX                    3
#define ET_ENABLE                   1
#define BETA_THRESHOLD              9.0/8.0
#define REP_THRESHOLD               9.0/16.0
#define PUN_THRESHOLD               7.0/16.0
#define A_SEG_THRESHOLD             360
#define A_SEG_THRESHOLD2            1013
#define E_SEG_THRESHOLD             1088
#define DIS_CRC_LEN                 24
// added for rtl polar decoder
#define POLAR_N_EXT_TYPE            2 // 1:prefix-0-enc(repeat-llr-dec), 2:append-0-enc(append-max-llr-dec)
#define POLAR_PM_DIST               1 // if !=1, RTL's rate1&spc proc should be different
#define MAX_PM_LENGTH               (MAX_LIST_LENGTH*POLAR_PM_DIST)
#define MAX_SUBTREE_NUM             50
#define POLAR_RTL_RESOURCE_NUM      1024
#define POLAR_MAX_PATH_NUM          64 //各子树左节点扩展的路径数最多为8*8
#define POLAR_MAX_RN_NV             32 //右节点Nv的最大值

//CRC define left-right swap
#define CRC6_POLY                   0x21
#define CRC11_POLY                  0x423
#define CRC24_POLY                  0xE88D4D
#define CRC16_POLY					0x1021
#define CRC24A_POLY					0x864CFB
#define CRC24B_POLY					0x800063
#define CRC24C_POLY					0xB2B117	

//FSCL algorithm node type define
#define RATE_0                      0
#define RATE_1                      1
#define SPC                         2
#define REP                         3
#define ARITRARY                    4
#define SPC_EXPAND_LIST_NUM         4
#define RATE1_EXPAND_LIST_NUM       2


//fixed point bit wideth
#define LLR_BIT_WIDTH               6
#define ALPHA_BIT_WIDTH             8
#define PM_BIT_WIDTH                12
#define FRACTION_BIT_WIDTH          2

//IPCORE Enable Flag
#define POLAR_IPCORE                0 // 0:不使用ipcore;

//Macro used for POLAR CODE End

//used for LDPC encoding and decoding
//#define NORM_FAC_MS 0.75//NMS coef, 0.0625*(1~16)
#define OFFSET_FAC_MS_BPSK  0.18 //OMS Coef for BPSK
#define OFFSET_FAC_MS_QPSK  0.1768 //OMS Coef for QPSK
#define OFFSET_FAC_MS_QAM16  0.3 //OMS Coef for QAM16
#define OFFSET_FAC_MS_QAM64  0.4 //OMS Coef for QAM64
#define OFFSET_FAC_MS_QAM256  0.7 //OMS Coef for QAM256
//#define NORM_FAC_MS_FIXP (INT32)(NORM_FAC_MS*(1<<(BIT_WIDTH-1)))//Q(N,1)TBD
#define OFFSET_FAC_MS_FIXP_BPSK  (INT32)(OFFSET_FAC_MS_BPSK*(1<<3))//Q(N,N-3)
#define OFFSET_FAC_MS_FIXP_QPSK  (INT32)(OFFSET_FAC_MS_QPSK*(1<<3))//Q(N,N-3)
#define OFFSET_FAC_MS_FIXP_QAM16  (INT32)(OFFSET_FAC_MS_QAM16*(1<<3))//Q(N,N-3)
#define OFFSET_FAC_MS_FIXP_QAM64  (INT32)(OFFSET_FAC_MS_QAM64*(1<<3))//Q(N,N-3)
#define OFFSET_FAC_MS_FIXP_QAM256  (INT32)(OFFSET_FAC_MS_QAM256*(1<<3))//Q(N,N-3)
#define MAX_Z_SIZE 384

#define BIT_WIDTH 8

#define LDPC_BG1   0//Base Graph #1
#define LDPC_BG2   1//Base Graph #2

#define LDPC_NMS  0//minmum sum
#define LDPC_OMS  1//offset minmum sum

#define LDPC_TPMP  0
#define LDPC_TDMP  1

#define LDPC_CRC_16  0
#define LDPC_CRC_24A  1
#define LDPC_CRC_24B  2
#define LDPC_CRC_24C  3

#define LDPC_CRC16_POLY  0x1021
#define LDPC_CRC24A_POLY  0x864CFB
#define LDPC_CRC24B_POLY  0x800063
#define LDPC_CRC24C_POLY  0xB2B117

#define SOFT  0
#define HARD  1
#define VER_NUM  2

#define CRC  0
#define LDPC  1

#if ((1 == FILESPRINT)||(2 == FILESPRINT)||(3 == FILESPRINT))
#define UE_NUM  32
#else
#define UE_NUM  8
#endif
#define HARQ_PROC_NUM  5

#ifndef CC_READFLAG
#define CC_READFLAG  (0) //1 - ldpc input read from file, 0 - random_source_gen_f
#endif

// add for c model
#define CaseListBufSize 100
#define CaseNameBufSize 500

#define MaxCellNum 4 // It supports max number of Ue in  C model
#define MaxDCI_Period 4 //
#define MAX_HARQ_NUM  16
#define MAX_SNR_NUM 20
#define MAX_CASE_NUM 2000

#ifdef MATLAB_MEX_FILE //matlab环境编译mex会自动define MATLAB_MEX_FILE

#define UL_MEX_FLAG  (1)
#define DL_MEX_FLAG  (1)

#include "mex.h"
#define printf mexPrintf

#else
	
#define UL_MEX_FLAG  (0) // 配置为0时，可以在C环境注释掉和mex相关的函数；matlab环境编译mex也不需要修改此处
#define DL_MEX_FLAG   (0)

#endif // MEX_FLAG_MATLAB

// Marco function used to set field value of structure parameter in Mex interface
// When invoking these macro function, need to define following these variable:
//	mxArray *pHeadAddr;
//  mxArray *pFieldPtr;
//  double  *pFieldData;

// Scalar value for structure field data
// For example: MX_FIELD_VALUE_SET(SimParam->PUSCH_RB_Num, int8, "PUSCH_RB_Num")
#define MX_FIELD_VALUE_SET(FieldVar, ValueType, FieldName)		   \
	pFieldPtr = mxGetField(pHeadAddr, 0, FieldName);			   \
	if (pFieldPtr != NULL)										   \
	{															   \
		FieldVar = (ValueType)*(double *)mxGetData(pFieldPtr);     \
	}

// Array for structure field data
// For example:	MX_FIELD_ARRAY_SET(SimParam->RB_BitMap, uint8, MAXRBNUM, "RB_BitMap")
#define MX_FIELD_ARRAY_SET(FieldVar, ValueType, ArraySize, FieldName)	\
	pFieldPtr = mxGetField(pHeadAddr, 0, FieldName);					\
	if (pFieldPtr != NULL)												\
	{																    \
		pFieldData = (double *)mxGetData(pFieldPtr);					\
		for (int i = 0; i < ArraySize; i++)								\
		{																\
			FieldVar[i] = (ValueType)pFieldData[i];						\
		}																\
	}

// 2-dimension matrix for structure field data
// For example:	MX_FIELD_MATRIX_SET(SimParam->pusch_re_flag, int8, MAXSYMNUM, SC_NUM, "pusch_re_flag")
#define MX_FIELD_MATRIX_SET(FieldVar, ValueType, RowNum, ColNum, FieldName)	\
	pFieldPtr = mxGetField(pHeadAddr, 0, FieldName);						\
	if (pFieldPtr != NULL)												\
	{																    \
		pFieldData = (double *)mxGetData(pFieldPtr);					\
		for (int iColIdx = 0; iColIdx < ColNum; iColIdx++)				\
		{																\
			for (int iRowIdx = 0; iRowIdx < RowNum; iRowIdx++)			\
			{															\
				FieldVar[iRowIdx][iColIdx] = (ValueType)*pFieldData;	\
				pFieldData += 1;										\
			}															\
		}																\
	}

// 3-dimension matrix for structure field data
// For example:	MX_FIELD_HD_MATRIX_SET(SimParam->pusch_re_flag_dmrsport, int8, MAXSYMNUM, LAYER_NUM, SC_NUM, "pusch_re_flag_dmrsport")
#define MX_FIELD_HD_MATRIX_SET(FieldVar, ValueType, PageNum, RowNum, ColNum, FieldName)	\
	pFieldPtr = mxGetField(pHeadAddr, 0, FieldName);								\
	if (pFieldPtr != NULL)															\
	{																				\
		pFieldData = (double *)mxGetData(pFieldPtr);								\
		for (int iPageIdx = 0; iPageIdx < PageNum; iPageIdx++)						\
		{																			\
			for (int iColIdx = 0; iColIdx < ColNum; iColIdx++)						\
			{																		\
				for (int iRowIdx = 0; iRowIdx < RowNum; iRowIdx++)					\
				{																	\
					FieldVar[iPageIdx][iRowIdx][iColIdx] = (ValueType)*pFieldData;	\
					pFieldData += 1;												\
				}																	\
			}																		\
		}																			\
	}

#define ASIC_CEVA_FLAG    0   //0---对应原始方案  1--对应的是ASIC方案 2---对应的是CEVA方案
#define FltPrintFlag	  0   //1--对应浮点打印  0---对应定点打印
#define diff_SNRdB_Flag   0   //1---对应开启量化信噪比测量。
#define PrintMode   0       //0--实部和虚部打印在一行，1---实部打印2行，用例量化信噪比测量数据的读取。

#define MAX_DOWN_SAMPLE_RATE   16		//单级多相滤波器最大降采样倍率

#endif
/********************************* END OF FILE *******************************/

